# -*- coding: UTF-8 -*-

from math import *
import random
from Univers import *
from Planete import Planete
from VaisseauV1 import *
from Ressources import *
from Unite import *
from joueur import *


class Model():
    def __init__(self,controleur,joueurs,seed):
        random.seed(seed)
        self.controleur = controleur
        self.univers=Univers(seed)
        compteur = 0
        self.compteur=0
       
        
        self.listeJoueurs = []
        for i in joueurs:
            if i == self.controleur.nomClient:
                self.monId = compteur
            self.listeJoueurs.append(Joueur1("joueur"+str(compteur), compteur))
            compteur+=1
        compteur=0
        for i in self.listeJoueurs:
            depx = random.randint(254,2966)
            depy = random.randint(254,1566)
            i.creerNouveauVaisseau("test"+str(compteur),"combat",depx,depy)
            i.creerNouveauVaisseau("mothership","mothership",depx+10,depy+10)  
            compteur+=1
            
        self.planeteCourante=None
        self.objet = None
        self.ennemi = None       
        self.univers.genererEtoiles()
        
        
    def creuserMinerais(self):
        for p in self.listeJoueurs[self.monId].planetes:
            self.listeJoueurs[self.monId].mineraux += p.calcRevenus()
        
    def afficherToutNosVaisseaux(self):
        for j in self.listeJoueurs:
            for v in j.vaisseaux:
                self.controleur.afficherVaisseau(v)
                
    def afficherToutNosBatiment(self):
        for b in self.planeteCourante.listeBatiments:
            self.controleur.afficherBatiment(b)
        
                
    def afficherNosUnites(self):
        for u in self.planeteCourante.listeUnite:
            self.controleur.afficherUnite(u)
            
    def afficherVuePlanete(self):
        self.afficherNosUnites()
        self.afficherToutNosBatiment()
    
    def afficherUnivers(self):
        self.afficherToutNosVaisseaux()
                
        for e in self.univers.listeEtoiles:
            if e.isAffiche or e.isVisite:
                self.controleur.afficherEtoile(e)
            for p in e.listePlanete:
                if p.isAffiche or p.isVisite:
                    self.controleur.afficherPlanete(p)
                    
    def isAuJoueur(self, id):
        if id==self.monId:
            return True
        else:
            return False
        
    def clicGauche(self,tags):
        if tags[0] == "Planete":
            for e in self.univers.listeEtoiles:
                if int(tags[2]) == e.idEtoile:
                    for p in e.listePlanete:
                        if int(tags[1]) == p.ID:
                            self.planeteCourante=p
                            self.controleur.afficherInfoPlanete(p)
       
        elif tags[0] == "Etoile":
            for e in self.univers.listeEtoiles:
                if int(tags[1]) == e.idEtoile:
                    self.controleur.afficherInfoEtoile(e)
        
        elif tags[0] == "Vaisseau" or tags[0] == "MotherShip":
            vaisseau = None
            
            for j in self.listeJoueurs:
                if(int(tags[2])==j.id):
                    idJoueur = j.id
                    for v in j.vaisseaux:
                        if(v.id == int(tags[1])):
                            self.controleur.afficherInfoVaisseau(v)
                            vaisseau = v
                            break
            if(idJoueur==self.monId):
                self.ajoutInListeVaisseauCourant(vaisseau)
                self.controleur.afficherVaisseauSelectionne()

        
        elif tags[0] == "Unite":
            for u in self.planeteCourante.listeUnite:
                if(int(tags[2])==self.monId):
                    if(u.id == int(tags[1])):
                        self.controleur.afficherInfoUnite(u)
                        self.ajoutInListeUnitesCourants(u)
                        self.controleur.afficherUniteSelectionne()
                        break

        elif tags[0] == "BlocRessource":
            self.controleur.afficherVuePlaneteBloc(tags[1],int(tags[2]))
        
        elif tags[0] == "caserne" or tags[0] == "mine":
            self.controleur.afficherInfoBatiment(int(tags[1]))
        
    
    def ajoutInListeVaisseauCourant(self,v):
        if len(self.listeJoueurs[self.monId].vaisseauxCourant) !=0:
            for vaisseau  in self.listeJoueurs[self.monId].vaisseauxCourant:
                vaisseau.isSelect=False
                self.listeJoueurs[self.monId].vaisseauxCourant.remove(vaisseau)
        self.listeJoueurs[self.monId].vaisseauxCourant.append(v)
        
    def ajoutInListeUnitesCourants(self,u):
        if len(self.planeteCourante.uniteCourant) !=0:
            for unite in self.planeteCourante.uniteCourant:
                self.planeteCourante.uniteCourant.remove(unite)
        self.planeteCourante.uniteCourant.append(u)
                                
  
    def clicDroit(self,clic,posx,posy):
        if(self.univers.isVueUnivers):
            if(len(self.listeJoueurs[self.monId].vaisseauxCourant) > 0):
                if clic:
                    if clic[0] == "Vaisseau":
                        for j in self.listeJoueurs:
                            for v in j.vaisseaux:
                                if (int(clic[1]) == v.id):
                                    if(v.iDjoueur != self.monId):
                                        idV=self.listeJoueurs[self.monId].vaisseauxCourant[0].id
                                        self.listeJoueurs[self.monId].vaisseauxCourant[0].isCombat = True
                                        self.controleur.envoyerAction(["combat",self.monId,idV,v.iDjoueur,v.id,"Vaisseau"])
                                        break
                    else:
                        if(len(self.listeJoueurs[self.monId].vaisseauxCourant) > 0):
                            for v in self.listeJoueurs[self.monId].vaisseauxCourant:
                              v.isCombat = False
                              action=["deplacementVaisseau", self.monId, v.id,posx,posy]
                              self.controleur.envoyerAction(action)

                else:
                    if(len(self.listeJoueurs[self.monId].vaisseauxCourant) > 0):
                        for v in self.listeJoueurs[self.monId].vaisseauxCourant:
                          v.isCombat = False
                          action=["deplacementVaisseau", self.monId, v.id,posx,posy]
                          self.controleur.envoyerAction(action)

                
        elif(not self.univers.isVueUnivers):
            
            if(len(self.planeteCourante.uniteCourant) > 0):
                if clic:
                    if clic[0] == "Unite":
                        for u in self.planeteCourante.listeUnite:
                            if (int(clic[1]) == u.id):
                                if(u.iDjoueur != self.monId):
                                    for i in self.planeteCourante.listeUnite:
                                        if(i.iDjoueur == self.monId):
                                            unite = i
                                            unite.isCombat = True
                                            self.controleur.envoyerAction(["combat",self.monId,unite.id,u.iDjoueur,u.id,"Unite"])
                                            break
                    else:
                        if(len(self.planeteCourante.uniteCourant) > 0):
                            for u in self.planeteCourante.listeUnite:
                              u.isCombat = False
                              action=["deplacementUnite", self.monId, u.id,posx,posy]
                              self.controleur.envoyerAction(action)

                else:
                    if(len(self.planeteCourante.uniteCourant) > 0):
                        for u in self.planeteCourante.listeUnite:
                          u.isCombat = False
                          action=["deplacementUnite", self.monId, u.id,posx,posy]
                          self.controleur.envoyerAction(action)

        
    
    def ajoutInListeVaisseau(self,v):
        for i in self.vaisseaux:
            self.vaisseaux.remove(i)
        
        self.vaisseaux.append(v)
        
     
    def deplacementVaisseau(self):
            for i in self.listeJoueurs:
                for v in i.vaisseaux:
                    if(v.ismoving):      
                        if self.univers.isVueUnivers:
                            self.controleur.afficherVaisseau(v)
                            self.controleur.afficherVaisseauSelectionne()
                        v.deplacerVaisseau()
                        
    def deplacementUnite(self):
        if(self.controleur.getTypeVue() == False):
            for u in self.planeteCourante.uniteCourant:
                if(u.ismoving):
                    self.controleur.afficherUnite(u)
                    self.controleur.afficherUniteSelectionne()
                    u.deplacerUnit()
                 

    def changeDestination(self,x,y,listeObjet):
        if(isinstance(listeObjet[0], Vaisseau)):
            for i in self.vaisseaux:
                i.setDestination(x,y,0)
        
        
    def check(self,o):
        var = True
        for v in self.listeJoueurs[self.monId].vaisseaux:
            if(v.iDjoueur==self.monId):
                if(isinstance(o,Planete)):
                    if((o.posX >= v.posx -250 and o.posX<= v.posx+250) and (o.posY >=v.posy-250 and o.posY<=v.posy+250)):
                        var=True
                        break
                    else:
                        var=False
                elif(isinstance(o,Etoile)):
                    if((o.x >= v.posx -250 and o.x<= v.posx+250) and (o.y >=v.posy-250 and o.y<=v.posy+250)):
                        var=True
                        break
                    else:
                        var=False
                
        return var
        
        
    def cercleVision(self):
        if self.univers.isVueUnivers:
            for v in self.listeJoueurs[self.monId].vaisseaux:
                    for e in self.univers.listeEtoiles:
                        if((e.x >= v.posx -250 and e.x<= v.posx+250) and (e.y >=v.posy-250 and e.y<=v.posy+250)):
                            if not(e.isAffiche):
                               e.isAffiche=True
                               e.isVisite=True
                               e.isChange=False
                               self.controleur.afficherEtoile(e)
                               
                                
                        elif(not(self.check(e))):
                            e.isAffiche=False
                            self.controleur.afficherEtoile(e)
                        
                        
                        for p in e.listePlanete:
                            if((p.posX >= v.posx -250 and p.posX<= v.posx+250) and (p.posY >=v.posy-250 and p.posY<=v.posy+250)):
                                if not(p.isAffiche):
                                    p.isAffiche=True
                                    p.isVisite=True
                                    p.isChange=False
                                    self.controleur.afficherPlanete(p)
                                 
                            elif(not(self.check(p))):
                                p.isAffiche=False
                                self.controleur.afficherPlanete(p)
                           
        
    def combat(self,objet,ennemi):

            if(objet and ennemi):
                if(objet.isAttacking):
                    if(objet.currenthp > 0 and ennemi.currenthp > 0):
                        if(objet.attaquer(objet,ennemi)):
                            self.controleur.dessinerLigneAttaque(objet,ennemi)
                        
        
                    elif(objet.currenthp <= 0):
                        self.supprimerObjet(objet)
                        objet.isAttacking = False
                        ennemi.isAttacked = False
                        objet.cible = None
                    
                    else:
                        self.supprimerObjet(ennemi)
                        objet.isAttacking = False
                        ennemi.isAttacked = False
                        objet.cible = None
                
    def trouverObjetParId(self,id,idJ,type):
        if(type == "Vaisseau"):
            for v in self.listeJoueurs[idJ].vaisseaux:
                if v.id==id:
                    return v
                
        elif(type=="Unite"):
            for e in self.univers.listeEtoiles:
                for p in e.listePlanete:
                    for u in p.listeUnite:
                        if u.id==id and u.iDjoueur==idJ:
                            return u
                        
        elif(type=="Planete"):
            for e in self.univers.listeEtoiles:
                for p in e.listePlanete:
                    if p.sysSolaire == idJ:
                        if(p.ID==id):
                            return p
        
            
    def supprimerObjet(self,objet):
        if(isinstance(objet, Vaisseau)):
                for j in self.listeJoueurs:
                    if(objet.iDjoueur == j.id):
                        for v in j.vaisseaux:
                            if(v.id == objet.id):
                                self.listeJoueurs[objet.iDjoueur].vaisseaux.remove(objet)
                                self.controleur.supprimerObjet(objet,"Vaisseau")
                                self.objet = None
                                self.ennemi = None
                                break
                        for vc in j.vaisseauxCourant:
                            if(vc.id == objet.id):
                                j.vaisseauxCourant.remove(objet)
                                self.controleur.afficherVaisseauSelectionne()
                                break
                
        elif(isinstance(objet, Unite)):
            for u in self.planeteCourante.listeUnite:
                if(u.id == objet.id):
                    self.planeteCourante.listeUnite.remove(objet)
                    self.controleur.supprimerObjet(objet,"Unite")
                    self.objet = None
                    self.ennemi = None
                    break
            for uc in self.planeteCourante.uniteCourant:
                if(uc.id == objet.id):
                    self.planeteCourante.uniteCourant.remove(objet)
                    self.controleur.afficherUniteSelectionne()
                    break
    
                        
    def checkCombats(self):
        for j in self.listeJoueurs:
            for v in j.vaisseaux:
                if v.isAttacking:
                    self.combat(v, v.cible)
                    
        
    def executerActions(self):
        if self.controleur.frameClient in self.controleur.actionsEnAttente.keys():
            action = self.controleur.actionsEnAttente[self.controleur.frameClient]
            if action[0]=="deplacementVaisseau":
                    for v in self.listeJoueurs[action[1]].vaisseaux:
                        if(v.id == action[2]):
                            v.setDestination(action[3],action[4],0)
                            v.isCombat = False
                            break
                        
            elif action[0]=="deplacementUnite":
                for u in self.planeteCourante.uniteCourant:
                    if(u.iDjoueur == action[1]):
                        if(u.id == action[2]):
                            u.setDestination(action[3],action[4])
                            u.isCombat = False
                            break
            
            elif action[0]=="combat":
                self.combat(self.trouverObjetParId(action[2], action[1], action[5]), self.trouverObjetParId(action[4], action[3], action[5]))               
                
                
                vaisseauAttaquant = self.trouverObjetParId(action[2], action[1], action[5])
                vaisseauAttaque = self.trouverObjetParId(action[4], action[3], action[5])
                
                if(vaisseauAttaque and vaisseauAttaquant):
                    vaisseauAttaquant.cible = vaisseauAttaque
                    if(not vaisseauAttaque.cible):
                        vaisseauAttaque.cible =vaisseauAttaquant
                    vaisseauAttaquant.isAttacking = True
                    vaisseauAttaque.isAttacking = True
                    
            elif action[0]=="creerVaisseau":

                self.listeJoueurs[action[1]].creerNouveauVaisseau(action[2], action[2], action[3], action[4])
                self.afficherToutNosVaisseaux()
            
            elif action[0]=="creerBatiment":
                self.listeJoueurs[action[1]].creerNouveauBatiment(action[2], action[3], action[4],self.trouverObjetParId(self.planeteCourante.ID, self.planeteCourante.sysSolaire, "Planete"))
                self.afficherToutNosBatiment()
                
            elif action[0]=="colonisation":
                self.listeJoueurs[action[1]].coloniser(self.trouverObjetParId(action[2], action[1], "Vaisseau"),(self.trouverObjetParId(action[3], action[4], "Planete")))
                self.listeJoueurs[action[1]].planetes.append(self.trouverObjetParId(action[3], action[4], "Planete"))
                
            del self.controleur.actionsEnAttente[self.controleur.frameClient]
            
            
    def getListeVaisseaux(self,idJ):
        return self.listeJoueurs[idJ].vaisseaux
    
    def getListeUnites(self):
        return self.planeteCourante.listeUnite
     
    def getListeVaisseauxCourant(self,idJ):
        return self.listeJoueurs[idJ].vaisseauxCourant
     
    def getIsUnivers(self):
        return self.univers.isVueUnivers
    
    def checkColo(self):
        if(self.planeteCourante.joueur == "Aucun" or self.planeteCourante.joueur == self.listeJoueurs[self.monId].nom):
            for j in self.listeJoueurs:
                for v in j.vaisseaux:
                    if(not v.ismoving):
                        if(len(v.listeUnites)>0):
                            self.controleur.envoyerAction(["colonisation",j.id,v.id,self.planeteCourante.ID,self.planeteCourante.sysSolaire])
    
    def vaisseauProche(self):
        vaisseau = None
        for v in self.listeJoueurs[self.monId].vaisseaux:
            if((abs(self.planeteCourante.posX - v.posx ) <= 60) and (abs(self.planeteCourante.posY - v.posy) <= 60)):
                vaisseau = v
                
        if(vaisseau == None):
            return False
        else:
            return True
            
    def actionModel(self):
        self.compteur+=1
        self.cercleVision()
        self.deplacementVaisseau()
        self.deplacementUnite()
        self.checkCombats()
        if self.compteur == 10:
            self.creuserMinerais()
            self.controleur.vue.afficherMinerais()
            self.compteur =0